/*

Foment

*/

#ifndef __EXECUTE_HPP__
#define __EXECUTE_HPP__

// ---- Instruction ----

#define MakeInstruction(op, arg)\
    MakeImmediate(((((FFixnum) (arg)) << 8) | (op & 0xFF)), InstructionTag)
#define InstructionOpcode(obj) ((FOpcode) (AsValue(obj) & 0xFF))
#define InstructionArg(obj) ((FFixnum) (AsValue(obj) >> 8))

/*
Each instruction consists of <opcode> <arg>. The <arg> is a FFixnum.

The virtual machine state consists of an AStack (and an AStackPtr); a CStack and (a CStackPtr);
a Frame, an ArgCount, an IP, and a Proc. The Frame is optionally a vector on the heap.
The IP (instruction pointer) is an index into the Proc's (procedure) code vector.
*/

typedef enum
{
    // Opcodes generated by the compiler.

    CheckCountOpcode = 0,
    RestArgOpcode,
    MakeListOpcode,
    PushCStackOpcode,
    PushNoValueOpcode,
    PushWantValuesOpcode,
    PopCStackOpcode,
    SaveFrameOpcode,
    RestoreFrameOpcode,
    MakeFrameOpcode,
    PushFrameOpcode,
    GetCStackOpcode,
    SetCStackOpcode,
    GetFrameOpcode,
    SetFrameOpcode,
    GetVectorOpcode,
    SetVectorOpcode,
    GetGlobalOpcode,
    SetGlobalOpcode,
    MakeBoxOpcode,
    GetBoxOpcode,
    SetBoxOpcode,
    DiscardResultOpcode, // Multiple values interacts with this opcode; use PopAStackOpcode instead
    PopAStackOpcode,
    DuplicateOpcode,
    ReturnOpcode,
    CallOpcode,
    CallProcOpcode,
    CallPrimOpcode,
    TailCallOpcode,
    TailCallProcOpcode,
    TailCallPrimOpcode,
    SetArgCountOpcode,
    MakeClosureOpcode,
    IfFalseOpcode,
    IfEqvPOpcode,
    GotoRelativeOpcode,
    GotoAbsoluteOpcode,
    CheckValuesOpcode,
    RestValuesOpcode,

    // Special opcodes not generated by the compiler.

    ValuesOpcode,
    ApplyOpcode,
    CaseLambdaOpcode,
    CaptureContinuationOpcode,
    CallContinuationOpcode,
    AbortOpcode,
    ReturnFromOpcode,
    MarkContinuationOpcode,
    PopDynamicStackOpcode
} FOpcode;

FObject CurrentParameters();

#endif // __EXECUTE_HPP__
